//package com.wingstudio.springcloud.redis;
//
//import com.wingstudio.springcloud.controller.aspect.RedisLockAspect;
//import lombok.Data;*
// * @Author ITcz
// * @Data 2021-05-01 - 17:06
//
//
//
//import com.wingstudio.springcloud.controller.aspect.RedisLockAspect;
//import org.apache.commons.lang.StringUtils;
//
//import java.util.HashMap;
//import java.util.Objects;
//import java.util.UUID;
//import java.util.function.Supplier;
//
//*
// * 编程式分布式锁
// * 添加锁的可入性  TODO
// * 对外只暴露execute方法
// *
//
//public class Lock {
//    //存放查看是否有这个锁
//    private HashMap<String, RedisLockAspect.Lock> lockMap = new HashMap();
//
//    String realKey = null;
//    Thread lockOwnerThread = null;
//    RedisLockAspect.SurvivalClamProcessor survivalClamProcessor = null;
//    Thread survivalThread = null;
//    int state = 0;
//
//    public Lock(String realKey) {
//        this.realKey = realKey;
//    }
//
//    public Thread getLockOwnerThread() {
//        return lockOwnerThread;
//    }
//
//    public void setLockOwnerThread(Thread lockOwnerThread) {
//        this.lockOwnerThread = lockOwnerThread;
//    }
//
//    public RedisLockAspect.SurvivalClamProcessor getSurvivalClamProcessor() {
//        return survivalClamProcessor;
//    }
//
//    public void setSurvivalClamProcessor(RedisLockAspect.SurvivalClamProcessor survivalClamProcessor) {
//        this.survivalClamProcessor = survivalClamProcessor;
//    }
//
//    public Thread getSurvivalThread() {
//        return survivalThread;
//    }
//
//    public void setSurvivalThread(Thread survivalThread) {
//        this.survivalThread = survivalThread;
//    }
//
//    public int getState() {
//        return state;
//    }
//
//    public void setState(int state) {
//        this.state = state;
//    }
//
//    private final Boolean tryLock(String prefix, String key, String requestId, int waitTime) {
//        long startTime = System.currentTimeMillis();
//        long endTime = startTime + waitTime * 1000;
//        try {
//            do {
//                final Thread current = Thread.currentThread();
//                int c = this.getState();
//                if (c == 0) {
//                    long lockTime = 10;
//                    if (redisLockService.lock(prefix, key, requestId, lockTime)) {
//                        lockOwnerThread = current;
//                        this.setState(c + 1);
//                        int time = (int) lockTime;
//                        survivalClamProcessor = new RedisLockAspect.SurvivalClamProcessor(prefix, requestId, requestId, time);
////                            (survivalThread = threadFactoryManager.getThreadFactory().newThread(survivalClamProcessor)).start();
//                        survivalThread = new Thread(survivalClamProcessor);
//                        survivalThread.start();
//                        logger.info("线程获取重入锁成功,锁的名称为{}", prefix);
//                        return Boolean.TRUE;
//                    }
//                } else if (lockOwnerThread == Thread.currentThread()) {
//                    if (c + 1 < 0) {
//                        throw new Error("Maximum lock count exceeded");
//                    }
//                    this.setState(c + 1);
//                    logger.info("线程重入锁成功,锁的名称为{},当前LockCount为{}", prefix, state);
//                    return Boolean.TRUE;
//                }
//                //尝试重新获取锁
//                int sleepTime = 100;
//                if (waitTime > 0) {
//                    logger.info("线程暂时无法获得锁,当前已等待{}ms,本次将再等待{}ms,锁的名称为{}", System.currentTimeMillis() - startTime, sleepTime, prefix);
//                    try {
//                        Thread.sleep(sleepTime);
//                    } catch (InterruptedException e) {
//                        logger.info("线程等待过程中被中断,锁的名称为{}", prefix, e);
//                    }
//                }
//            } while (System.currentTimeMillis() <= endTime);
//            if (waitTime == 0) {
//                logger.info("线程获得锁失败,将放弃获取锁,锁的名称为{}", prefix);
//            } else {
//                logger.info("线程获得锁失败,之前共等待{}ms,将放弃等待获取锁,锁的名称为{}", System.currentTimeMillis() - startTime, prefix);
//            }
//            return Boolean.FALSE;
//        } catch (Exception e) {
//            return Boolean.FALSE;
//        }
//    }
//
//    private final void unLock(String prefix, String key, String requestId) {
//        if (lockOwnerThread == Thread.currentThread()) {
//            int c = this.getState() - 1;
//            if (c == 0) {
//                this.setLockOwnerThread(null);
//                survivalClamProcessor.stop();
//                survivalThread.interrupt();
//                this.setSurvivalClamProcessor(null);
//                this.setSurvivalThread(null);
//                this.setState(c);
//                redisLockService.releaseDistributedLock(prefix, key, requestId);
//                logger.info("重入锁LockCount-1,线程已成功释放锁,锁的名称为{}", prefix);
//            } else {
//                this.setState(c);
//                logger.info("重入锁LockCount-1,锁的名称为{}，剩余LockCount为{}", prefix, c);
//            }
//        }
//    }
//
//
//    public <T> T execute(Supplier<T> supplier, String prefix, String key, int waitTime) {
//        String randomValue = UUID.randomUUID().toString();
//        Boolean holdLock = Boolean.FALSE;
//        try {
//            if (holdLock = this.tryLock(prefix, key, randomValue, waitTime)) {
//                return supplier.get();
//            }
//            return null;
//        } catch (Exception e) {
//            logger.error("execute error", e);
//            return null;
//        } finally {
//            if (holdLock) {
//                this.unLock(prefix, key, randomValue);
//            }
//        }
//    }
//
//    public RedisLockAspect.Lock getLock(String prefix, String lockKey) {
//        String realKey = StringUtils.isEmpty(prefix) ? lockKey : (prefix.concat(":").concat(lockKey));
//        if (lockMap.containsKey(realKey)) {
//            return lockMap.get(realKey);
//        } else {
////                Lock lock = new Lock(finalprefix, lockRedisClient, threadFactoryManager);
//            RedisLockAspect.Lock lock = new RedisLockAspect.Lock(realKey);
//            RedisLockAspect.Lock existLock = lockMap.putIfAbsent(realKey, lock);
//            return Objects.nonNull(existLock) ? existLock : lock;
//        }
//    }
//
//
//}
